package petertel.pbx.conf.extensions;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import petertel.pbx.utils.ConfigItem;
import petertel.pbx.utils.ConfigItem.Flag;
import petertel.pbx.utils.ConfigParser;
import petertel.pbx.utils.ConfigSection;
import petertel.pbx.utils.ConfigWriter;

@Controller
@Scope(value = "session")
@RequestMapping(value = "/extensionsConf")
public class ExtensionsConf {

	private ConfigItem config;
	private String currentContextName;// request level

	@RequestMapping(value = "/show")
	public String show(String contextName) {
		currentContextName = contextName;
		return "extensionsConf_show";
	}

	@RequestMapping(value = "/reset")
	public String reset(String contextName) {
		config = ConfigParser.parse("/etc/asterisk/extensions.conf");
		return show(contextName);
	}

	@RequestMapping(value = "/addContext")
	public String addContext(String contextName) {
		boolean duplicated = false;
		String[] contexts = getContexts();
		for (int i = 0; i < contexts.length; i++) {
			if (contexts[i].equals(contextName)) {
				duplicated = true;
				break;
			}
		}
		if (duplicated) {
			return show(contextName);
		} else {
			ConfigSection csection = new ConfigSection(contextName);
			config.addChild(csection);
			ConfigWriter.write("/etc/asterisk/extensions.conf", config);
			return reset(contextName);
		}
	}

	@RequestMapping(value = "/removeContext")
	public String removeContext(String contextName) {
		Iterator<ConfigItem> iter = config.getChildren();
		while (iter.hasNext()) {
			ConfigItem child = iter.next();
			Context context = new Context(child);
			if (!context.getName().equals(contextName)) {
				continue;
			}
			if (child.getFlag() == Flag.insert) {
				iter.remove();
			} else {
				child.remove();
			}
			break;
		}
		ConfigWriter.write("/etc/asterisk/extensions.conf", config);
		return reset(null);
	}

	public boolean isDirty() {
		return false;
	}

	public String[] getContexts() {
		List<String> list = new ArrayList<String>();
		for (Iterator<ConfigItem> iter = config.getChildren(); iter.hasNext();) {
			Context context = new Context(iter.next());
			String name = context.getName();
			if (name.equals("general")) {
				;
			} else if (name.equals("globals")) {
				;
			} else {
				list.add(name);
			}
		}
		return (String[]) list.toArray(new String[0]);
	}

	public Iterator<Extension> getExtensions() {
		if (currentContextName != null)
			for (Iterator<ConfigItem> iterContext = config.getChildren(); iterContext
					.hasNext();) {
				Context context = new Context(iterContext.next());
				if (currentContextName.equals(context.getName())) {
					return context.getExtensions();
				}
			}
		return null;
	}

	public String getCurrentContextName() {
		return currentContextName;
	}

	public Iterator<Statement> getStatements() {
		final Iterator<Extension> ITER = getExtensions();
		return new Iterator<Statement>() {
			private Iterator<Statement> iter = null;
			private Statement stmt = null;
			private boolean toggle;
			private String extName;

			public boolean hasNext() {
				if (ITER == null) {
					return false;
				}
				if (stmt == null && iter != null && iter.hasNext()) {
					stmt = iter.next();
				}
				if (stmt == null && ITER.hasNext()) {
					iter = ITER.next().getStatements();
					return hasNext();
				}
				return stmt != null;
			}

			public Statement next() {
				Statement temp = stmt;
				stmt = null;
				if (temp.getName() != null && !temp.getName().equals(extName)) {
					extName = temp.getName();
					toggle = !toggle;
				}
				temp.setToggle(toggle);
				return temp;
			}

			public void remove() {
				;
			}

		};
	}
}
